package com.bootdo.app.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.bootdo.change.service.impl.AutoChangeService;
import com.bootdo.goods.domain.TGoodsAllocationAloneDO;
import com.bootdo.goods.domain.TGoodsAllocationDO;
import com.bootdo.goods.service.TGoodsAllocationAloneService;
import com.bootdo.goods.service.TGoodsAllocationService;
import com.bootdo.output.domain.OutStorageDO;
import com.bootdo.output.domain.OutStorageDetailDO;
import com.bootdo.output.service.OutStorageDetailService;
import com.bootdo.output.service.OutStorageService; 
import com.bootdo.task.domain.TTaskDO;
import com.bootdo.task.domain.TTaskDatilDO;
import com.bootdo.task.service.TTaskDatilService;
import com.bootdo.task.service.TTaskService;
@Service
public class CreateTaskService {
	 
		//商品
		@Autowired
		private  OutStorageService outStorageService;
		@Autowired
		private  OutStorageDetailService outStorageDetailService;
		@Autowired
		private  TGoodsAllocationService tGoodsAllocationService;
		@Autowired
		private  TTaskService tTaskService;
		@Autowired
		private  TTaskDatilService tTaskDatilService;
		@Autowired
		private AutoChangeService autoChangeService;
		@Autowired
		private TGoodsAllocationAloneService tGoodsAllocationAloneService;

		/**
		 * 由订单生成任务单
		 */
	public  void createTasks(Long providerId) {
		//商品数组 
		Set<Long> set = new HashSet<>();
		//数组集合 的长度可以哪一个变量接收  变量可以率先声明到外面 不使用时清空 或归零
		Map<String, Object> map = new HashMap<>();
		// 查询已下单的订单 //获取所有订单加急优先 按照时间有限 可以查询两次进行拼接
		map.put("outstorageStatus", "12202");//	已下单
		map.put("sort", "outstorage_orderid");
		map.put("order", "desc");
		map.put("providerId", providerId);
		List<OutStorageDO> list = outStorageService.list(map);
		good:for (OutStorageDO out : list) { // 所有订单 
			// 按照订单编号查询所有订单子表
			// 生成map条件 //map 可声明在外 等待优化 list 同样
			Map<String, Object> outId = new HashMap<>();
			outId.put("outId", out.getOutstorageId());
			List<OutStorageDetailDO> outStorageDetailList = outStorageDetailService.list(outId);
			boolean isMelody = false;// 是否需要调仓
			for (OutStorageDetailDO detail : outStorageDetailList) {// 查询该订单详情分拣区是否满足需求
				// 根据商品编号 获取货位 
				Long goodId = detail.getDatilGoodsid();
				if(set.equals(goodId))
					break good;
				set.add(goodId);
				Integer number = detail.getDatilAmount();
				Integer quantity = 0;// 仓库总量
				Integer sortingNumber = 0;// 分拣区总量
				Map<String, Object> alone = new HashMap<>();
				Map<String, Object> GId = new HashMap<>();
				GId.put("providerId", providerId);
				GId.put("order", "asc");
				GId.put("allocationType", "122003");//零散
				GId.put("allocationStatus", "120003");//有货状态
				List<TGoodsAllocationDO> sortingAllocation = tGoodsAllocationService.list(GId);
				for (TGoodsAllocationDO tGoodsAllocationDO : sortingAllocation) {
					//根据货位编号 和商品 查出实体 计算出数量 
					alone.put("allocationNumber", tGoodsAllocationDO.getAllocationNumber());
					alone.put("goodsId", goodId);
					List<TGoodsAllocationAloneDO> allocationAloneDOs = tGoodsAllocationAloneService.list(alone);
					for (TGoodsAllocationAloneDO tGoodsAllocationAloneDO : allocationAloneDOs) {
						sortingNumber +=	tGoodsAllocationAloneDO.getGoodsNumber();
					}
				}
				GId.put("goodsId", goodId);
				GId.put("sort", "(goods_number-remark)");//分拣区减去 
				// 循环货位查出 1 2 层的数量
				GId.put("allocationType", "122001");//分拣位
				// 查询到有此商品的分拣货位
				  sortingAllocation = tGoodsAllocationService.list(GId);
				for (TGoodsAllocationDO place : sortingAllocation) {
					Integer goodNumber = place.getGoodsNumber();
					Integer remarkNumber = new Integer(place.getRemark());
					sortingNumber += (goodNumber-remarkNumber); // 计算分拣区数量 减去分拣锁定位置
				}
				// 如果分拣数量大于等于要发货的数量 则获取所有分拣区的编号
				if (number > sortingNumber) {
					isMelody = true;//  
					// 调用调仓接口
					Integer required = quantity - sortingNumber;// 所需数量
					String order = null;
					if(out.getOutstorageOrderid() == 1001001) {
						order = "1";
					}
					autoChangeService.autoChange(goodId, required, providerId, out.getOutstorageId(),order, null);
					
				
					//
				}
			}
			if (!isMelody) {
				OutStorageDO outStorage = new OutStorageDO();
				outStorage.setOutstorageId(out.getOutstorageId());
				outStorage.setOutstorageStatus("12203");
				outStorageService.update(outStorage);
				TTaskDO ttask = new TTaskDO();
				ttask.setTaskGrade(out.getOutstorageOrderid().toString());
				ttask.setTaskRemark(out.getOutstorageId().toString());
				ttask.setTaskStatus("12001");//未发布
				ttask.setTaskStopTime(new Date()); 
				ttask.setTaskSupplierId(out.getProviderId());
				ttask.setTaskShopId(out.getOutstorageShopid());//添加门店信息
				tTaskService.save(ttask);// 分拣单
				Long id = Long.valueOf(ttask.getTaskId());
				// 循环所有该订单的货物在分拣区那个位置 
				// 循环每个详情在分拣区的位置 生成分拣详情单 更改状态
				for (OutStorageDetailDO detail : outStorageDetailList) {// 订单详情
					Long goodId = detail.getDatilGoodsid(); // 商品编号
					Integer number = detail.getDatilAmount(); // 商品数量、
					// 查询每个商品在库中位置
					Integer num = 0;//查询分拣位数量
					List<String> datilId = new ArrayList<>();//总共的分拣位编号
					List<Integer> datilNumberInte = new ArrayList<>(); //每个分拣位所拥有的数量
					List<Integer> remarkNumberInte = new ArrayList<>(); //每个分拣位所拥有的数量
					List<Long> datilIdNumber = new ArrayList<>(); //每个分拣位位置编号
					Map<String, Object> GId = new HashMap<>();
					int count = 0;
					GId.put("goodsId", goodId);
					GId.put("order", "asc");
					GId.put("providerId", providerId);
					GId.put("allocationStatus", "120003");//有货状态
					Map<String, Object> alone = new HashMap<>();
					GId.put("allocationType", "122003");//零散
					List<TGoodsAllocationDO> sortingAllocation = tGoodsAllocationService.list(GId);
					for (TGoodsAllocationDO tGoodsAllocationDO : sortingAllocation) {
						Integer s = 0;//商品总数
						//根据货位编号 和商品 查出实体 计算出数量 
						alone.put("allocationType", "122003");
						alone.put("allocationStatus", "120003");
						alone.put("allocationNumber", tGoodsAllocationDO.getAllocationNumber());
						alone.put("goodsId", goodId);
						List<TGoodsAllocationAloneDO> allocationAloneDOs = tGoodsAllocationAloneService.list(map);
						for (TGoodsAllocationAloneDO tGoodsAllocationAloneDO : allocationAloneDOs) {
							s += 	tGoodsAllocationAloneDO.getGoodsNumber();
						}
						if(s>0) {
							Long getAllID = tGoodsAllocationDO.getAllocationId();
							Integer goodNumber = s;
							Integer remarkNumber = 0;
							String getAllocationId = tGoodsAllocationDO.getAllocationNumber();
							if(goodNumber - remarkNumber <= 0) {
								continue;
							}
							
							 num += (goodNumber-remarkNumber);
							 datilId.add(count,getAllocationId ); 
							 datilNumberInte.add(count, goodNumber);
							 remarkNumberInte.add(count,remarkNumber);
							 datilIdNumber.add(count,getAllID);
							 count++;
							if (num >= number) {//如果当前货架累计总数大于等于需要分拣的数量 break
								break;
							}
						}
					}
					GId.put("goodsId", goodId);
					GId.put("sort", "(goods_number-remark)");//分拣区减去 
					// 循环货位查出 1 2 层的数量
					GId.put("allocationType", "122001");//分拣位
					sortingAllocation = tGoodsAllocationService.list(GId);
					
					for (int i = 0; i < sortingAllocation.size(); i++) {
						
						
						Long getAllID = sortingAllocation.get(i).getAllocationId();
						Integer goodNumber = sortingAllocation.get(i).getGoodsNumber();
						Integer remarkNumber = new Integer(sortingAllocation.get(i).getRemark());
						String getAllocationId = sortingAllocation.get(i).getAllocationNumber();
						if(goodNumber - remarkNumber <= 0) {
							continue;
						}
						
						 num += (goodNumber-remarkNumber);
						 datilId.add(count,getAllocationId ); 
						 datilNumberInte.add(count, goodNumber);
						 remarkNumberInte.add(count,remarkNumber);
						 datilIdNumber.add(count,getAllID);
						 count++;
						if (num >= number) {//如果当前货架累计总数大于等于需要分拣的数量 break
							break;
						}
						
					}
					Integer sumNumber = 0; //除去最后一个货位其他货位需要拿的数量
					 for (int i = 0; i < datilNumberInte.size()-1; i++) {
					 sumNumber+=datilNumberInte.get(i); 
					 }
					 //获取最后一个仓位需要拿多少
					 Integer last = number - sumNumber ;
					 datilNumberInte.add(datilNumberInte.size()-1, last);//设置最后一个 
					 //生成订单  
					 for (int i = 0; i < datilId.size(); i++) {
						TTaskDatilDO datilDO = new TTaskDatilDO();
						datilDO.setTdGid(goodId);//商品编号
						datilDO.setTdInitalAllocation(datilId.get(i));
						datilDO.setTdNumber(datilNumberInte.get(i));
						datilDO.setTdStatus("12005");//待完成
						datilDO.setTdUnit(detail.getDatilPricingManner());
						datilDO.setTdTaskId(id);
						datilDO.setTdTaskSpecification(detail.getDatilStandard());
						tTaskDatilService.save(datilDO);
						
						//先查看是否是零散货位 
						/**
						 * 如果是残次品 循环查询当前商品 数量相减
						 */
						//锁定货位数量
						map.clear();
						map.put("allocationNumber", datilId.get(i));
						List<TGoodsAllocationDO> alist = tGoodsAllocationService.list(map);
						if(alist.size()>0) {
						
							TGoodsAllocationDO scattered = alist.get(0);
							if(scattered.getAllocationType().equals("122003")) {
								alone.put("allocationNumber", scattered.getAllocationNumber());//货位编号
								alone.put("goodsId", goodId);
								List<TGoodsAllocationAloneDO> allocationAloneDOs = tGoodsAllocationAloneService.list(alone);
								TGoodsAllocationAloneDO tGoodsAllocationAloneDO = allocationAloneDOs.get(0) ;
								TGoodsAllocationAloneDO tGoodsAllocationAlone = new TGoodsAllocationAloneDO();
								tGoodsAllocationAlone.setId(tGoodsAllocationAloneDO.getId());
							 	Integer alonenumber = tGoodsAllocationAloneDO.getGoodsNumber() - datilNumberInte.get(i);
							 	tGoodsAllocationAlone.setGoodsNumber(alonenumber);
							 	tGoodsAllocationAloneService.update(tGoodsAllocationAlone);
							}
						}
						TGoodsAllocationDO allocationDO = new TGoodsAllocationDO();
						Integer r = remarkNumberInte.get(i);
						r+=datilNumberInte.get(i);
						allocationDO.setAllocationId(datilIdNumber.get(i));
						allocationDO.setRemark(r.toString());
						tGoodsAllocationService.update(allocationDO);
					}
					 //改变订单状态
				}
			} else {
				// 修改该订单状态 调仓完成更改状态
			}
		}
		// 查询单个订单每个商品分拣区有无货物
		// 进行货物数量锁定
	}
}
